package com.yystar.security.support.util;


import java.security.MessageDigest;
import java.sql.Blob;
import java.sql.SQLException;
import java.text.CharacterIterator;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.text.StringCharacterIterator;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * Text Utility
 * 
 * @author Worm Yung
 * @version 1.0 (2007-Oct-30)
 * 
 * Revision 2007-Oct-30 First Production
 */
public abstract class StringUtil {

    private static final char[] _HEX_DIGITS = {
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
        'e', 'f'
    };
    
	// --------------------------------------------------------------------------------------- Static Methods

    /**
     *  DateTime Format
     */
	public static SimpleDateFormat getDateFormatter(String format) {
		SimpleDateFormat sdf = null;

		sdf = new SimpleDateFormat(format);

		return sdf;
	}

    /**
     * Number Format 
     * @param fractionDigits
     * @param useGrouping
     * @return
     */
	public static NumberFormat getNumberFormatter(int fractionDigits, boolean useGrouping) {
		NumberFormat nf = null;

		nf = NumberFormat.getInstance();

		nf.setMinimumFractionDigits(fractionDigits);
		nf.setMaximumFractionDigits(fractionDigits);
		nf.setGroupingUsed(useGrouping);

		return nf;
	}

	
	/**
	 * format Number not 4 and 5
	 * @param price
	 * @return
	 */
	public static double getNumberFormat(double price){		
		return Math.floor(price * 100)/100;
	}
	
	
	/**
	 * replace Text
	 * @param text
	 * @return
	 */
	public static String parseSQLText(String text) {
		String result = "";

		result = text.replaceAll("'", "''");

		return result;
	}

   /**
    * NULL conversion
    * @param text
    * @return
    */
	public static String parseNullString(Object text) {
		return StringUtil.parseNullString(text, "");
	}

    /**
     * IF text is null so use defaultValue replace
     * @param text
     * @param defaultValue
     * @return
     */
	public static String parseNullString(Object text, String defaultValue) {
		String result = "";

		if (text instanceof String) {
			if (text != null && !"null".equals(text)) {
				result = (String) text;
			} else {
				result = defaultValue;
			}
		} else {
			if (text != null) {
				result = text.toString();
			} else {
				result = defaultValue;
			}
		}

		return result;
	}

   /**
	 * object conversion Integer
	 * @param text
	 * @return
	 * @throws Exception
	 */
	public static String parseZeroString(Object text) throws Exception {
		return StringUtil.parseNullString(text, "0");
	}
    
	/**
	 * String conversion Integer
	 * @param text
	 * @param defaultValue
	 * @return
	 * @throws Exception
	 */
	public static int parseIntString(String text, int defaultValue) throws Exception {
		int result = defaultValue;

		if ((text != null) && (!text.equals(""))) {
			result = Integer.parseInt(text);
		}

		return result;
	}

    /**
     * String conversion Long
     * @param text
     * @param defaultValue
     * @return
     * @throws Exception
     */
	public static long parseLongString(String text, int defaultValue) throws Exception {
		long result = defaultValue;

		if ((text != null) && (!text.equals(""))) {
			result = Long.parseLong(text);
		}

		return result;
	}
	
	/**
     * String conversion boolean
     * @param text
     * @return
     */
    public static boolean parseBooleanString(String text) {
        return StringUtil.parseBooleanString(text, false);
    }

    /**
     * String conversion boolean
     * @param text
     * @param defaultValue
     * @return
     */
    public static boolean parseBooleanString(String text, boolean defaultValue) {
        boolean result = defaultValue;

        if ((text != null) && (!text.equals(""))) {
            result = Boolean.parseBoolean(text);
        }

        return result;
    }

    /**
     * String conversion Double
     * @param text
     * @return
     * @throws Exception
     */
	public static double parseDoubleString(String text) throws Exception {
		return StringUtil.parseDoubleString(text, -1);
	}

   /**
    * String Conversion Double
    * @param text
    * @param defaultValue
    * @return
    * @throws Exception
    */
	public static double parseDoubleString(String text, int defaultValue) throws Exception {
		double result = defaultValue;

		if ((text != null) && (!text.equals(""))) {
			result = Double.parseDouble(text);
		}

		return result;
	}

    /**
     * String Conversion Date
     * @param text
     * @return
     * @throws Exception
     */
	public static java.util.Date parseDateString(String text) throws Exception {
		return StringUtil.parseDateString(text, null);
	}

    /**
     * String Conversion Date(yyyy-MM-dd)
     * @param text
     * @param defaultValue
     * @return
     * @throws Exception
     */
	public static java.util.Date parseDateString(String text, java.util.Date defaultValue) throws Exception {
		java.util.Date result = defaultValue;
		SimpleDateFormat sdf = null;

		sdf = new SimpleDateFormat("yyyy-MM-dd");

		if ((text != null) && (!text.equals(""))) {
			text = text.replaceAll("/", "-");

			try {
				result = sdf.parse(text);
			} catch (ParseException ex) {

			}
		}

		return result;
	}

	/**
	 * String Conversion DateTime(yyyy-MM-dd HH:mm:ss)
	 * @param text
	 * @param defaultValue
	 * @return
	 * @throws Exception
	 */
	public static java.util.Date parseDateTimeString(String text, java.util.Date defaultValue) throws Exception {
		java.util.Date result = defaultValue;
		SimpleDateFormat sdf = null;

		sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

		if ((text != null) && (!text.equals(""))) {
			text = text.replaceAll("/", "-");

			try {
				result = sdf.parse(text);
			} catch (ParseException ex) {
				
			}
		}

		return result;
	}

	/**
	 * Date Format
	 * @param sdf
	 * @param date
	 * @return
	 */
	public static String formatDate(SimpleDateFormat sdf, java.util.Date date) {
		String result = "";

		try {
			if (date != null) {
				result = sdf.format(date);
			}
		} catch (Exception ex) {

		}

		return result;
	}

    /**
     * String Conversion HTML
     * @param text
     * @return
     */
	public static String convertTextToHtml(String text) {
		String result = "";
		text = StringUtil.parseNullString(text);
		result = text.replaceAll("\n", "<br />").replaceAll("\r", "").replaceAll("'", "\"");

		return result;
	}

	/**
	 *  String Conversion text
	 * @param text
	 * @return
	 */
	public static String convertNameText(String text) {
		String result = "";
		text = StringUtil.parseNullString(text);
		result = text.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll("'", "&#39;").replaceAll("\n", " ");
		return result;
	}
	
	/**
	 *  String Conversion text
	 * @param text
	 * @return
	 */
	public static String convertTextName(String text) {
		String result = "";
		text = StringUtil.parseNullString(text);
		result = text.replaceAll("&amp;","&").replaceAll("&lt;","<").replaceAll("&gt;",">").replaceAll("&#39;", "'");
		return result;
	}
	
    /**
     * encrypt 
     * @param originalText
     * @return
     * @throws Exception
     */
	public static String digestMD5(String originalText) throws Exception {
		byte buf[] = originalText.getBytes();
		StringBuffer hexString = new StringBuffer();
		String result = "";
		String digit = "";

		try {
			MessageDigest algorithm = MessageDigest.getInstance("MD5");
			algorithm.reset();
			algorithm.update(buf);

			byte[] digest = algorithm.digest();

			for (int i = 0; i < digest.length; i++) {
				digit = Integer.toHexString(0xFF & digest[i]);

				if (digit.length() == 1) {
					digit = "0" + digit;
				}

				hexString.append(digit);
			}

			result = hexString.toString();
		} catch (Exception ex) {
			result = "";
		}

		return result;
	}

   /**
    * Clean String Head And End
    * @param token
    * @return
    */
	public static String trimToken(String token) {
		String result = "";

		if (token.startsWith("\"") && token.endsWith("\"")) {
			result = token.substring(1, token.length() - 1);
		} else {
			result = token;
		}

		return result;
	}

	/**
	 * format String
	 * @param text
	 * @return
	 */
	public static String parseText(String text) {

		text = text.replace("\n", " ");
		text = text.replace("\r", "");
		return text;

	}
	
	/**
	 * format String
	 * @param text
	 * @return
	 */
	public static String parseTextAlertNotice(String text) {
		
		text = text.replace("\r", "");
		text = text.replace("\n", "\\n");
		return text;
		
	}

	/**
	 * Number Format
	 * @param f
	 * @return
	 */
	public static String getPercent(double f) {
		java.text.NumberFormat nf = java.text.NumberFormat.getPercentInstance();
		return nf.format(f);
	}


	/**
	 * Collection Add String Conversion String
	 * @param collection
	 * @param separator
	 * @return
	 */
	public static String join(Collection<?> collection, String separator) {
		if (collection == null)
			return "";

		StringBuilder result = new StringBuilder();

		Iterator<?> iterator = collection.iterator();
		while (iterator.hasNext()) {
			result.append(iterator.next().toString());
			result.append(separator);
		}

		int lastIndexOf = result.lastIndexOf(separator);
		if (lastIndexOf == -1) {
			lastIndexOf = 0;
		}
		return result.substring(0, lastIndexOf);
	}

	/**
	 * String[] Add String Conversion String 
	 * @param strings
	 * @param separator
	 * @return
	 */
	public static String join(String[] strings, String separator) {
		if (strings == null)
			return "";

		StringBuilder result = new StringBuilder();

		for (int i = 0; i < strings.length; i++) {
			result.append(strings[i]);
			result.append(separator);
		}

		int lastIndexOf = result.lastIndexOf(separator);
		if (lastIndexOf == -1) {
			lastIndexOf = 0;
		}
		return result.substring(0, lastIndexOf);
	}
	
	/**
	 * int[] Add String Conversion String
	 * @param ints
	 * @param separator
	 * @return
	 */
	public static String join(int[] ints, String separator) {
		if (ints == null)
			return "";
		
		StringBuilder result = new StringBuilder();
		
		for (int i = 0; i < ints.length; i++) {
			result.append(ints[i]);
			result.append(separator);
		}
		
		int lastIndexOf = result.lastIndexOf(separator);
		if (lastIndexOf == -1) {
			lastIndexOf = 0;
		}
		
		return result.substring(0, lastIndexOf);
	}
    
	/**
	 * String Conversion HTML
	 * @param s
	 * @return
	 */
	public static String escapeHTML(String s) {
		if (s == null) return "";
		
		StringBuffer sb = new StringBuffer();
		boolean firstBlankChar = true;
		int n = s.length();
		for (int i = 0; i < n; i++) {
			char c = s.charAt(i);
			if (c == ' ') {
				if (firstBlankChar) {
					sb.append(" ");
					firstBlankChar = false;
				} else {
					sb.append("&nbsp;");
				}
			} else {
				firstBlankChar = true;
				switch (c) {
				case '<':
					sb.append("&lt;");
					break;
				case '>':
					sb.append("&gt;");
					break;
				case '&':
					sb.append("&amp;");
					break;
				case '"':
					sb.append("&quot;");
					break;
				/*
				case 'à':
					sb.append("&agrave;");
					break;
				case 'À':
					sb.append("&Agrave;");
					break;
				case 'â':
					sb.append("&acirc;");
					break;
				case 'Â':
					sb.append("&Acirc;");
					break;
				case 'ä':
					sb.append("&auml;");
					break;
				case 'Ä':
					sb.append("&Auml;");
					break;
				case 'å':
					sb.append("&aring;");
					break;
				case 'Å':
					sb.append("&Aring;");
					break;
				case 'æ':
					sb.append("&aelig;");
					break;
				case 'Æ':
					sb.append("&AElig;");
					break;
				case 'ç':
					sb.append("&ccedil;");
					break;
				case 'Ç':
					sb.append("&Ccedil;");
					break;
				case 'é':
					sb.append("&eacute;");
					break;
				case 'É':
					sb.append("&Eacute;");
					break;
				case 'è':
					sb.append("&egrave;");
					break;
				case 'È':
					sb.append("&Egrave;");
					break;
				case 'ê':
					sb.append("&ecirc;");
					break;
				case 'Ê':
					sb.append("&Ecirc;");
					break;
				case 'ë':
					sb.append("&euml;");
					break;
				case 'Ë':
					sb.append("&Euml;");
					break;
				case 'ï':
					sb.append("&iuml;");
					break;
				case 'Ï':
					sb.append("&Iuml;");
					break;
				case 'ô':
					sb.append("&ocirc;");
					break;
				case 'Ô':
					sb.append("&Ocirc;");
					break;
				case 'ö':
					sb.append("&ouml;");
					break;
				case 'Ö':
					sb.append("&Ouml;");
					break;
				case 'ø':
					sb.append("&oslash;");
					break;
				case 'Ø':
					sb.append("&Oslash;");
					break;
				case 'ß':
					sb.append("&szlig;");
					break;
				case 'ù':
					sb.append("&ugrave;");
					break;
				case 'Ù':
					sb.append("&Ugrave;");
					break;
				case 'û':
					sb.append("&ucirc;");
					break;
				case 'Û':
					sb.append("&Ucirc;");
					break;
				case 'ü':
					sb.append("&uuml;");
					break;
				case 'Ü':
					sb.append("&Uuml;");
					break;
				case '®':
					sb.append("&reg;");
					break;
				case '©':
					sb.append("&copy;");
					break;
				case '€':
					sb.append("&euro;");
					break;
				*/
				default:
					sb.append(c);
					break;
				}
			}
		}
		return sb.toString();
	}
 
	/**
	 * String Conversion HTML
	 * @param string
	 * @return
	 */
	public static String stringToHTMLString(String string) {
		if (string == null) return "";
		
		StringBuffer sb = new StringBuffer(string.length());
		// true if last char was blank
		boolean lastWasBlankChar = false;
		int len = string.length();
		char c;

		for (int i = 0; i < len; i++) {
			c = string.charAt(i);
			if (c == ' ') {
				// blank gets extra work,
				// this solves the problem you get if you replace all
				// blanks with &nbsp;, if you do that you loss 
				// word breaking
				if (lastWasBlankChar) {
					lastWasBlankChar = false;
					sb.append("&nbsp;");
				} else {
					lastWasBlankChar = true;
					sb.append(' ');
				}
			} else {
				lastWasBlankChar = false;
				//
				// HTML Special Chars
				if (c == '"')
					sb.append("&quot;");
				else if (c == '&')
					sb.append("&amp;");
				else if (c == '<')
					sb.append("&lt;");
				else if (c == '>')
					sb.append("&gt;");
				else if (c == '\n')
					// Handle Newline
					sb.append("&lt;br/&gt;");
				else {
					int ci = 0xffff & c;
					if (ci < 160)
						// nothing special only 7 Bit
						sb.append(c);
					else {
						// Not 7 Bit use the unicode system
						sb.append("&#");
						sb.append(new Integer(ci).toString());
						sb.append(';');
					}
				}
			}
		}
		return sb.toString();
	}
	
	
	/**
	 * String Conversion HTML
	 * @param string
	 * @return
	 */
	public static String stringUploadToHTMLString(String string) {
		if (string == null) return "";
		
		StringBuffer sb = new StringBuffer(string.length());
		// true if last char was blank
		boolean lastWasBlankChar = false;
		int len = string.length();
		char c;

		for (int i = 0; i < len; i++) {
			c = string.charAt(i);
			if (c == ' ') {
				// blank gets extra work,
				// this solves the problem you get if you replace all
				// blanks with &nbsp;, if you do that you loss 
				// word breaking
				if (lastWasBlankChar) {
					lastWasBlankChar = false;
					sb.append("&nbsp;");
				} else {
					lastWasBlankChar = true;
					sb.append(' ');
				}
			} else {
				lastWasBlankChar = false;
				//
				// HTML Special Chars
				if (c == '"')
					sb.append("&quot;");
				else if (c == '&')
					sb.append("&amp;");
				else if (c == '<')
					sb.append("&lt;");
				else if (c == '>')
					sb.append("&gt;");
				else if (c == '\n')
					// Handle Newline
					sb.append("&lt;br/&gt;");
				else 
					sb.append(c);
			}
		}
		return sb.toString();
	}
	
	/**
	 * 
	 * @param blob
	 * @return
	 * @throws SQLException
	 */
	public static String blobToString(Blob blob) throws SQLException {
		StringBuilder result = new StringBuilder();
		
		long i = 1;
		if (blob != null){
			while (i <= blob.length()) {
				result.append(new String(blob.getBytes(i, 2000)));
				i += 2000;
			}
		}
		return result.toString();
	}
	
	static char[] hex = "0123456789ABCDEF".toCharArray();
	public static String escapeJSON(String str) {
		if (str == null) {
			return null;
		}
		
		StringBuilder result = new StringBuilder();
		
		CharacterIterator it = new StringCharacterIterator(str);

        for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
            if (c == '"') {
            	result.append("\\\"");
            } else if (c == '\\') {
            	result.append("\\\\");
            } else if (c == '/') {
            	result.append("\\/");
            } else if (c == '\b') {
            	result.append("\\b");
            } else if (c == '\f') {
            	result.append("\\f");
            } else if (c == '\n') {
            	result.append("\\n");
            } else if (c == '\r') {
            	result.append("\\r");
            } else if (c == '\t') {
            	result.append("\\t");
            } else if (Character.isISOControl(c)) {
            	result.append("\\u");

                int n = c;

                for (int i = 0; i < 4; ++i) {
                    int digit = (n & 0xf000) >> 12;

                	result.append(hex[digit]);
                    n <<= 4;
                }
            } else {
            	result.append(c);
            }
        }
        
        return result.toString();
	}
	
	/**
	 * check text rule
	 * @param str
	 * @return
	 */
	public static boolean checkTextRule(String str) {
		String regex = "^([\\-\\(\\)\\'a-zA-Z0-9\\s\u4e00-\u9fa5]){2,}$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}
	
	/**
	 * check color rule
	 * @param str
	 * @return
	 */
	public static boolean checkColorRule(String str) {
		String regex = "^#([a-fA-F0-9]{6})$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}
	
	/**
	 * check code rule
	 * @param str
	 * @return
	 */
	public static boolean checkCodeRule(String str) {
		String regex = "^([a-zA-Z0-9]){2,}$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}
	
	public static String replaceStr(String str) {
		if (str == null) {
			return null;
		}
		
		return str.replaceAll("\\s", "\u0000");
	}
	
	/**
	 * 判断字符串是否为空
	 * @param s 需要验证的字符串
	 * @return
	 */
	public static boolean isNull(String s) {
	   return (s == null || s.length() < 1);
	}
	
	/**
	 * 判断字符串是否不为空
	 * @param s 需要验证的字符串
	 * @return
	 */
	public static boolean isNotNull(String s) {
	    return !isNull(s);
	}
	
	/**
	 * to HexString
	 * @param i
	 * @return
	 */
	public static String toHexString(int i) {
        char[] buffer = new char[8];

        int index = 8;

        do {
            buffer[--index] = _HEX_DIGITS[i & 15];

            i >>>= 4;
        }
        while (i != 0);

        return new String(buffer, index, 8 - index);
    }
}
